package com.chenxinzhimusic.data

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.serialization.json.Json

val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "chenxinzhiMusic")

val musicSettingKey: Preferences.Key<String> = stringPreferencesKey("musicSetting")
val playListKey: Preferences.Key<String> = stringPreferencesKey("playList")
val loveKey: Preferences.Key<String> = stringPreferencesKey("love")


suspend inline fun <reified T> Context.saveDataContent(key: Preferences.Key<String>, body: T) =
    coroutineScope {
        launch(Dispatchers.IO) {
            val json = Json.encodeToString(body)
            dataStore.edit {
                it[key] = json
            }
        }
    }

inline fun <reified T> Context.getDataContent(key: Preferences.Key<String>): Flow<T?> {
    return dataStore.data.map { it ->
        it[key].let {
            if (it.isNullOrBlank()) {
                return@map null
            }
            Json.decodeFromString<T>(it)
        }
    }.flowOn(Dispatchers.IO)

}

suspend inline fun <reified T> Context.getDataContentValue(key: Preferences.Key<String>): T? {
    return withContext(Dispatchers.IO) {
        dataStore.data
            .map { preferences ->
                preferences[key].let {
                    if (it.isNullOrBlank()) {
                        null
                    } else {
                        Json.decodeFromString<T>(it)
                    }
                }
            }
            .first()
    }
}

